package com.sz.app.edi.job.email;

import com.sz.app.edi.constants.EdiErrorCodes;
import com.sz.common.base.job.JobScheduler;
import com.sz.common.base.logger.Logger;
import com.sz.common.base.utils.JsonUtils;
import com.sz.common.base.utils.StringUtils;
import com.sz.common.core.system.entity.SysMail;
import com.sz.common.core.system.service.SysMailService;
import com.sun.mail.smtp.SMTPAddressFailedException;
import com.sun.mail.util.MailConnectException;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailAuthenticationException;
import org.springframework.mail.MailSendException;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import javax.mail.MessagingException;
import javax.mail.SendFailedException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("sendEmailJobScheduler")
public class SendEmailJobSchedulerImpl implements JobScheduler {

    Logger logger = Logger.getLogger(this.getClass());

    @Autowired
    private SysMailService sysMailService;

    @Autowired
    private EmailService emailService;

    @Autowired
    private Configuration configuration;

    @Override
    public void execute() {
        final long start = System.currentTimeMillis();
        logger.info("==============start sendEmailJobScheduler");
        List<SysMail> mailList = sysMailService.getAllNeedSentMails();
        logger.info("get mails size : " + mailList.size());
        if (mailList != null && mailList.size() > 0) {
            for (SysMail sysMail : mailList) {
                logger.info("232323", sysMail);
                sendEmail(sysMail);
            }
        }
        final long end = System.currentTimeMillis();
        logger.info("==============end sendEmailJobScheduler,use time:" + (end - start) + "ms");
    }

    private void sendEmail(SysMail sysMail) {
        String content = "";
        if (StringUtils.isEmpty(sysMail.getTemplate())) {
            content = sysMail.getBody();
        }
        else {
            try {
                Template template = configuration.getTemplate(sysMail.getTemplate());
                logger.info("template的数据为："+template);
                logger.info("====1=====");
                String body = sysMail.getBody();
                logger.info("====2=====");
                Map<String, Object> dataModel = new HashMap<>();
                logger.info("====3=====");

                dataModel = JsonUtils.toObject(body, Map.class);
                logger.info("====4=====");
                content = FreeMarkerTemplateUtils.processTemplateIntoString(template, dataModel);
                logger.info("====5=====");
            } catch (Exception e) {
                logger.error("解析数据异常", e);
                sysMailService.setMailFailStatus(sysMail.getId(), String.valueOf(EdiErrorCodes.ERROR_EMAIL_DATA_ERROR.getCode()),e.getMessage());
            }
        }
        try {
            logger.info("====6=====");
            emailService.sendHtmlMail(sysMail.getSubject(), content, sysMail.getReceiver().split(";"));
            logger.info("====7=====");
            sysMailService.updateSentResult(sysMail.getId(), true, null,null);
            logger.info("send email success");
        } catch (MessagingException e) {
            logger.error(e.getMessage());
            sysMailService.updateSentResult(sysMail.getId(), false, String.valueOf(EdiErrorCodes.ERROR_EMAIL_CONFIG_ERROR.getCode()),e.getMessage());
        } catch (MailSendException e) {
            logger.error(e.getMessage());
            if (e.getMessageExceptions() != null && e.getMessageExceptions().length > 0) {
                for (int i = 0; i < e.getMessageExceptions().length; i++) {
                    if (e.getMessageExceptions()[i] instanceof SendFailedException) {
                        SendFailedException sendFailedException = (SendFailedException) e.getMessageExceptions()[i];
                        if (sendFailedException.getNextException() instanceof SMTPAddressFailedException) {
                            sysMailService.setMailFailStatus(sysMail.getId(), String.valueOf(EdiErrorCodes.ERROR_EMAIL_ADDRESS_NOT_FOUND.getCode()),e.getMessage());
                        }
                        else {
                            sysMailService.setMailFailStatus(sysMail.getId(), String.valueOf(EdiErrorCodes.ERROR_EMAIL_UNKNOWN_ERROR.getCode()),e.getMessage());
                        }
                        return;
                    }
                    else if (e.getMessageExceptions()[i] instanceof MailConnectException) {
                        sysMailService.updateSentResult(sysMail.getId(), false, String.valueOf(EdiErrorCodes.ERROR_EMAIL_CONNECT_ERROR.getCode()),e.getMessage());
                        return;
                    }
                    else {
                        sysMailService.updateSentResult(sysMail.getId(), false, String.valueOf(EdiErrorCodes.ERROR_EMAIL_UNKNOWN_ERROR.getCode()),e.getMessage());
                        return;
                    }
                }
            }
            else {
                sysMailService.updateSentResult(sysMail.getId(), false, String.valueOf(EdiErrorCodes.ERROR_EMAIL_UNKNOWN_ERROR.getCode()),e.getMessage());
            }
        } catch (MailAuthenticationException e) {
            logger.error(e.getMessage());
            sysMailService.updateSentResult(sysMail.getId(), false, String.valueOf(EdiErrorCodes.ERROR_EMAIL_AUTHENTICATION_ERROR.getCode()),e.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage());
            sysMailService.updateSentResult(sysMail.getId(), false, String.valueOf(EdiErrorCodes.ERROR_EMAIL_UNKNOWN_ERROR.getCode()),e.getMessage());
        }
    }
}
